package com.webserver.core;

import com.webserver.annotation.Controller;
import com.webserver.annotation.RequestMapping;
import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URISyntaxException;

/**
 * DispatcherServlet实际是由SpringMVC框架提供的一个类，用于和Tomcat整合并负责
 * 接手处理请求的工作
 * <p>
 * Servlet是Java EE里的一个接口，运行在服务端的小程序
 * 有一个抽象方法用于处理某个事务
 * public void service(HttpServletRequest request, HttpServletResponse response)
 * <p>
 * SpringMVC框架提供的DispatcherServlet就实现了该接口并重写了service方法，与Tomcat整合后，
 * Tomcat在处理请求的环节的环节就可以和调用DispatcherServlet的service方法将请求对象与响应对象传递进去
 * 由SpringMVC框架完成处理请求的操作。
 *
 * @author Chen
 */
public class DispatcherServlet {
    private static DispatcherServlet instance = new DispatcherServlet();
    private static File root;
    private static File staticDir;

    static {
        try {
            root = new File(DispatcherServlet.class.getClassLoader().getResource(".").toURI());
            staticDir = new File(root, "static");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    private DispatcherServlet() {
    }

    public static DispatcherServlet getInstance() {
        return instance;
    }

    public void service(HttpServletRequest request, HttpServletResponse response) {
        // 判断用户的请求路径不应当含有参数部分，所以uri不适用
        String path = request.getRequestURI();
        System.out.println("抽象路径：" + path);
//        UserController controller = new UserController();
//        // 判断是否为请求业务
//        if ("/regUser".equals(path)) {
//            controller.reg(request, response); // 执行注册
//        } else if ("/loginUser".equals(path)){
//            controller.login(request, response); // 执行登录
//        } else {
//            File contentFile = new File(staticDir, path);
//            // 判断请求的文件真实存在且确定是一个文件
//            if (!contentFile.isFile()) {
//                response.setStatusCode(404);
//                response.setStatusReason("NotFound");
//                response.setContentFile(new File(staticDir, "404.html"));
//            } else {
//                response.setContentFile(contentFile);
//            }
//        }
//        response.addHeader("Server", "BirdServer");
        try {
            File dir = new File(DispatcherServlet.class.getClassLoader().getResource("./com/webserver/controller").toURI());
            File[] subs = dir.listFiles(f -> f.getName().endsWith(".class"));
            for (File sub : subs) {
                String fileName = sub.getName();
                String className = fileName.substring(0, fileName.indexOf("."));
                className = "com.webserver.controller." + className;
                Class<?> clazz = Class.forName(className);
                if (clazz.isAnnotationPresent(Controller.class)) {
                    Object obj = clazz.newInstance();
                    Method[] methods = clazz.getDeclaredMethods();
                    for (Method method : methods) {
                        if (method.isAnnotationPresent(RequestMapping.class)) {
                            RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                            String value = requestMapping.value();
                            if (value.equals(path)) {
                                method.invoke(obj, request, response);
                                return;
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {

        }
        File contentFile = new File(staticDir, path);
        // 判断请求的文件真实存在且确定是一个文件
        if (!contentFile.isFile()) {
            response.setStatusCode(404);
            response.setStatusReason("NotFound");
            response.setContentFile(new File(staticDir, "404.html"));
        } else {
            response.setContentFile(contentFile);
        }
        response.addHeader("Server", "BirdServer");
    }
}
